#ifndef EGG_GPUPROGRAM_H
#define EGG_GPUPROGRAM_H

#include "Shader.h"
#include "GPUParam.h"

namespace egg{

    class GPUProgram{
    protected:
        class ShaderSlot{
        public:
            ShaderSlot(){
                mVersion=-1;
            }
            inline bool checkVersion(){
                return mVersion==mShader->getVersion();
            }
            inline void updateVersion(){
                mVersion=mShader->getVersion();
            }
        public:
            int32 mVersion;
            ShaderPtr mShader;
        };
        typedef map<string,GPUParam> ParamMap;
    public:
        GPUProgram();
        ~GPUProgram();
    public:
        void update();
        void addShader(ShaderPtr _shader);
        bool checkParam(GPUParam* _param);

        inline uint32 getID(){
            return mID;
        }
        inline int32 getVersion(){
            return mVersion;
        }
        inline ShaderPtr getShader(ShaderType _type){
            return mShaders[_type].mShader;
        }
        inline const ParamMap& getActiveParams(){
            return mActiveParams;
        }
        inline GLint _getParamLoc(const string& _name){
            return glGetUniformLocation(mID,_name.c_str());
        }
        inline void setParam(const string& _name,uint32 _param){
            glUniform1i(_getParamLoc(_name),_param);
        }
        inline void activate(){
            gDevice->setGPUProgram(mID);
        }
    protected:
        GLuint mID;
        int32 mVersion;
        ShaderSlot mShaders[ST_Max];
        ParamMap mActiveParams;
    };

    typedef shared_ptr<GPUProgram> GPUProgramPtr;

}

#endif